/**
 * 
 */
package de.cbf.cam.dsa.tavern.carte.ui;



import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

import de.cbf.cam.dsa.tavern.carte.model.entities.Meal;
import de.cbf.cam.dsa.tavern.carte.model.entities.MealType;
import de.cbf.cam.dsa.tavern.carte.ui.interfaces.ICompositePersistEntity;

/**
 * @author Stefan Alter
 *
 */
public class CompositeMeals extends Composite implements ICompositePersistEntity {

	private Table tableCarte;

	/**
	 * @param parent
	 * @param style
	 */
	public CompositeMeals(Composite parent, int style) {
		super(parent, style);
		initialize();		
	}

	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() {
        GridLayout layout = new GridLayout(1,false);
			layout.marginHeight = 0;
			layout.marginWidth	= 0;
			layout.marginLeft	= 0;
			layout.marginRight	= 0;
			layout.marginBottom = 0;
			layout.marginTop	= 0;
		//	
		this.setLayout(layout);
		//
		tableCarte = new Table(this, SWT.BORDER|SWT.FULL_SELECTION);
		tableCarte.setHeaderVisible(true);
		tableCarte.setLayoutData(new GridData(GridData.FILL_BOTH));
		tableCarte.setLinesVisible(true);		
			TableColumn columnMealName = new TableColumn(tableCarte, SWT.NONE);
			columnMealName.setWidth(80);
			columnMealName.setText("Name");
			TableColumn columnMealType = new TableColumn(tableCarte, SWT.NONE);
			columnMealType.setWidth(60);
			columnMealType.setText("Typ");
			TableColumn columnMealPrice = new TableColumn(tableCarte, SWT.NONE);
			columnMealPrice.setWidth(38);
			columnMealPrice.setText("Preis");
			TableColumn columnDescription = new TableColumn(tableCarte, SWT.NONE);
			columnDescription.setWidth(140);
			columnDescription.setText("Beschreibung");	
		//
		registerListeners(); 
	}

	private void registerListeners() {
		tableCarte.addSelectionListener	(mealSelection);	
		tableCarte.addKeyListener		(mealDelete);		
		tableCarte.addMouseListener		(mealDoubleClick);		
		//
		ToolTipDescription toolTip = new ToolTipDescription();
		tableCarte.addListener(SWT.MouseHover,toolTip);
		tableCarte.addListener(SWT.MouseMove,toolTip);
	}

	public void setCarte(Iterator<Meal> iterator){
		setMealsToTable(iterator);
	}
	@SuppressWarnings("unused")
	private List<Meal> getMealsFromTable() {
		List<Meal> carte = new ArrayList<Meal>();
		for (int i = 0; i < tableCarte.getItemCount(); i++) {
			Meal meal = (Meal)tableCarte.getItem(i).getData();
			carte.add(meal);
		}
		return carte;
	}
	
	private void setMealsToTable(Iterator<Meal> iterator) {
		tableCarte.removeAll();		
		while(iterator.hasNext()){
			Meal meal = (Meal) iterator.next();
			TableItem item = new TableItem(tableCarte, SWT.NORMAL);
			item.setText(0,meal.getName());
			MealType type = meal.getType();
			if(type != null){
				item.setText(1,type.getName());
			}else{
				item.setText(1,"");
			}			
			item.setText(2,meal.getPrice().toString());
			item.setText(3,meal.getDescription());
			
			item.setData(meal);
		}		
	}
	
	private int indexOfMealInTable(Meal meal){
		for(int i = 0 ;i < tableCarte.getItemCount();i++){
			TableItem item = tableCarte.getItem(i);
			Meal itemMeal = (Meal)item.getData();
			if(meal.equals(itemMeal)){
				return i;
			}
		}
		return -1;
	}
	
	public Meal getSelectedMeal() {
		if(tableCarte.getSelectionCount()>0){
			Meal meal = (Meal)tableCarte.getSelection()[0].getData();
			return meal;
		}
		return null;
		
	}
	public void setSelectedMeal(Meal meal){		
		int indexTable = indexOfMealInTable(meal);
		if(indexTable > -1){
			tableCarte.setSelection(indexTable);
		}
	}	
	@Override
	public Object getSelectedObject() {
		return getSelectedMeal();
	}
	@Override
	public Object[] getSelectedObjects() {
		TableItem[] selection = tableCarte.getSelection();
		if(selection.length == 0) return null; //for interface continuity
		Object[] objects = new Object[selection.length];
		for (int i = 0; i < selection.length; i++) {
			TableItem item = selection[i];
			objects[i] = item.getData();
		}		
		return objects;
	}

	@Override
	public void deSelectAll() {
		tableCarte.deselectAll();		
	}

	@Override
	public void setObjects(Iterator<? extends Object> iterator) {
		//use templist
		Collection<Meal> resultList = new ArrayList<Meal>();
		while (iterator.hasNext()) {
			Object object = (Object) iterator.next();
			if (object instanceof Meal) {
				Meal meal = (Meal) object;
				resultList.add(meal);
			}
		}
		setCarte(resultList.iterator());		
	}
	
	private Collection<ActionListener> mealSelectionListeners = new ArrayList<ActionListener>();  //  @jve:decl-index=0:
	@Override
	public boolean registerSelectionListener(ActionListener listener) {
		boolean result = mealSelectionListeners.add(listener);			
		return result;
	}

	@Override
	public boolean deRegisterSelectionListener(ActionListener listener) {
		boolean result = mealSelectionListeners.remove(listener);		
		return result;		
	}
	
	private MealSelection mealSelection = new MealSelection();  //  @jve:decl-index=0:
	private class MealSelection extends SelectionAdapter{
		@Override
		public void widgetSelected(SelectionEvent e) {		
			ActionEvent event = new ActionEvent(CompositeMeals.this, ActionEvent.ACTION_PERFORMED,"exportCarte");
			for (Iterator<ActionListener> iterator = mealSelectionListeners.iterator(); iterator.hasNext();) {
				ActionListener listener = iterator.next();
				listener.actionPerformed(event);				
			}
		}		
	}
	private Collection<ActionListener> mealDoubleClickListeners = new ArrayList<ActionListener>();
	@Override
	public boolean registerDoubleClickListener(ActionListener listener) {
		return mealDoubleClickListeners.add(listener);		
	}

	@Override
	public boolean deRegisterDoubleClickListener(ActionListener listener) {
		return mealDoubleClickListeners.remove(listener);		
	}
	
	private MealDoubleClickAdvancer mealDoubleClick = new MealDoubleClickAdvancer();	
	private class MealDoubleClickAdvancer extends MouseAdapter{			
		@Override
		public void mouseDoubleClick(MouseEvent e) {
			ActionEvent event = new ActionEvent(CompositeMeals.this, ActionEvent.ACTION_PERFORMED, "MealDoubleClick");
			for (ActionListener listener : mealDoubleClickListeners) {
				listener.actionPerformed(event);
			}
		}				
	}
	
	private Collection<ActionListener> ListChangedListeners = new ArrayList<ActionListener>();
	public boolean registerListChangedListener(ActionListener listener){
		return ListChangedListeners.add(listener);
	}
	public boolean deRegisterListChangedListener(ActionListener listener){
		return ListChangedListeners.remove(listener);
	}	
	protected void notifyListChanged() {
		ActionEvent event = new ActionEvent(CompositeMeals.this, ActionEvent.ACTION_PERFORMED, "ListChanged");
		for (ActionListener listener : ListChangedListeners) {
			listener.actionPerformed(event);
		}
	}		
	
	private Collection<ActionListener> deleteListeners = new ArrayList<ActionListener>();  //  @jve:decl-index=0:
	public boolean registerDeleteListener(ActionListener listener){
		return deleteListeners.add(listener);
	}
	public boolean deRegisterDeleteListener(ActionListener listener){
		return deleteListeners.remove(listener);
	}
	private MealDeleteAdvancer mealDelete = new MealDeleteAdvancer();  //  @jve:decl-index=0:
	private class MealDeleteAdvancer extends KeyAdapter{
		@Override
		public void keyPressed(KeyEvent e) {
			if(e.keyCode == SWT.DEL){
				ActionEvent event = new ActionEvent(CompositeMeals.this, ActionEvent.ACTION_PERFORMED, "deleteMeal");
				for (ActionListener listener : deleteListeners) {
					listener.actionPerformed(event);
				}
			}			
		}		
	}
	
	private class ToolTipDescription implements Listener{
		private Shell tip ;	
		private Label label;
		@Override
		public void handleEvent(Event event) {
			int type = event.type;
			switch (type) {
				case SWT.MouseHover:{
					TableItem item = tableCarte.getItem(new Point(event.x, event.y));
			        if (item != null) {
			            if (tip != null && !tip.isDisposed()){
			            	tip.dispose();
			            }
			            Display display = Display.getCurrent();
			            tip = new Shell(display, SWT.ON_TOP | SWT.BALLOON);
			            tip.setLayout(new GridLayout());
			            label = new Label(tip, SWT.NONE);
			            label.setLayoutData(new GridData(GridData.FILL_BOTH));
			            label.setForeground(display
			                .getSystemColor(SWT.COLOR_INFO_FOREGROUND));
			            label.setBackground(display
			                .getSystemColor(SWT.COLOR_INFO_BACKGROUND));			            
			            label.setText(item.getText(3));
			           
//			            Point eventDisplay = tableCarte.toDisplay(event.x,event.y);
//			            tip.setBounds(eventDisplay.x,eventDisplay.y,label.getSize().x,label.getSize().y);
			            Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			            Rectangle rect = item.getBounds(0);
			            Point pt = tableCarte.toDisplay(rect.x, rect.y);
			            tip.setBounds(pt.x, pt.y, size.x, size.y);			           
			            tip.setVisible(true);
			          }
					break;
				}
				case SWT.MouseMove:{
					if(tip != null){
						tip.dispose();
					}
				}
			}
			
		}		
	}

	

	
	

	

	
}  //  @jve:decl-index=0:visual-constraint="10,10"
